# -*- coding: utf-8 -*-
import hashlib
import json
import logging
import time
from collections import OrderedDict

import requests
from django.conf import settings

from common.cache import redis_cache
from common.stats import MG_BIGBANG_COLL as mg
from common.utils.exceptions import ParamError
from common.withdraw import check_daily_risk
from common.withdraw.db import withdraw_success_action, withdraw_failed_action

_LOGGER = logging.getLogger('alipay')

_GATEWAY = 'https://trans.9127pay.com/m/{}?t={}&sign={}'

_APPID_ = 'BSCP100'
APP_CONF = {
    _APPID_: {
        'API_KEY': 'ff30d30975974f6e902c34505e2845fb'
    },
}
# cd /opt/admin/enabled/app;/home/ubuntu/.pyenv/versions/casino/bin/python manage.py trans_alipay
_GROUP_ERROR_MSG = {
    'Success': u'成功',
    'EXCEED_LIMIT_SM_AMOUNT': u'单笔转账给个人支付宝账号最多5万元，转账给企业支付宝账号最多10万元，单笔最低转账金额0.1元',
    'PERM_AML_NOT_REALNAME_REV': u'根据监管部门的要求，需要收款用户补充身份信息才能继续操作',
    'PAYEE_USER_INFO_ERROR': u'支付宝账号和姓名不匹配，请确认姓名是否正确',
    'PAYEE_ACC_OCUPIED': u'该手机号对应多个支付宝账户，请传入收款方姓名确定正确的收款账号',
    'PERMIT_NON_BANK_LIMIT_PAYEE': u'根据监管部门的要求，对方未完善身份信息或未开立余额账户，无法收款',
    'PAYER_CERT_EXPIRED': u'根据监管部门的要求，需要付款用户更新身份信息才能继续操作',
    'PAYEE_NOT_EXIST': u'收款账号不存在',
    'EXCEED_LIMIT_PERSONAL_SM_AMOUNT': u'转账给个人支付宝账户单笔最多5万元',
    'EXCEED_LIMIT_UNRN_DM_AMOUNT': u'收款账户未实名，单日最多可收款1000元',
    'isv.invalid-parameter:payee_account': u'收款账号参数错误',
    'PAYEE#_NOT#_EXIST': u'收款账号不存在',
    'unknown-sub-code': u'	未知错误',
}


def _get_api_key(mch_id):
    return APP_CONF[mch_id]['API_KEY']


def generate_sign(s):
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    return m.hexdigest()


def _verify_notify_sign(jsonbody, t, sign, token):
    calculated_sign = generate_sign(jsonbody + str(t) + token)
    if sign.lower() != calculated_sign.lower():
        _LOGGER.info("group_new_withdraw sign: %s, calculated sign: %s", sign, calculated_sign)
        raise ParamError('sign not pass, data: %s' % jsonbody)


def check_group_new_withdraw_notify_sign(request):
    d = dict(request.GET.iteritems())
    _LOGGER.info("group_new_withdraw notify body: %s, d: %s", request.body, d)
    _verify_notify_sign(request.body, d['t'], d['sign'], _get_api_key(_APPID_))
    data = json.loads(request.body)
    pay_id = data['order_id']
    trade_status = int(data['code'])
    if not pay_id:
        _LOGGER.error("group_new_withdraw fatal error, data: %s" % data)
        raise ParamError('group_new_withdraw event does not contain valid pay ID')

    if trade_status != 10000:
        sub_msg = _GROUP_ERROR_MSG.get(data['msg']) or u'未知错误'
        withdraw_failed_action(pay_id, data['order_amout'], data['code'],
            data['msg'], sub_msg, data['trade_no'])
        return

    amout = data['order_amout']
    if withdraw_success_action(pay_id, amout, data['trade_no']):
        _LOGGER.info('Auto trans alipay, check_group_new_withdraw_notify_sign succ')
        check_daily_risk(int(amout))
        redis_cache.set_withdraw_status('group_new_withdraw', 0)


def group_withdraw_new_pay(order, amount, alipay_num, alipay_name):
    oid = order.id
    user_id = order.user_id
    user_stats = mg.user_stats.find_one({'_id': user_id}) or {}
    device_type = 'ios' if user_stats.get('chn', '').startswith('ios') else 'android'
    device_ip = user_stats.get('ip') or '1.1.1.1'
    device_id = user_stats.get('aid') or 'abcdef123456'
    p_dict = OrderedDict((
        ('order_id', str(oid)),
        ('type', 0),
        ('amount', str(amount)),
        ('fullname', alipay_name.encode('utf8')),
        ('account', alipay_num),
        ('callback_url', "%s%s" % (settings.EXCHANGE_CALLBACK_URL, _APPID_)),
        ('device_type', device_type),
        ('device_id', device_id),
        ('device_ip', device_ip),
        ('player_id', str(user_id)),
    ))
    jsonbody = json.dumps(p_dict)
    timestamp = int(time.time())
    s = jsonbody + str(timestamp) + _get_api_key(_APPID_)
    sign = generate_sign(s)
    url = _GATEWAY.format(_APPID_, timestamp, sign)
    _LOGGER.info("group_withdraw_new_pay create : %s, %s", url, jsonbody)
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    response = requests.post(url, data=jsonbody, headers=headers, timeout=10)
    _LOGGER.info("group_withdraw_new_pay response : %s, %s, %s", response.status_code, response.text, oid)
    if 'success' not in response.text:
        _LOGGER.error("group_withdraw_new_pay  response err: %s, %s, %s", response.status_code, response.text, oid)
        raise Exception(response.text)


